import SessionBody from '@/components/DataPreview/session/content';
import DirectoryViewer from '@/components/Directory/views';
import { loadFileMenus, operatesToMenus } from '@/executor/fileOperate';
import { useFlagCmdEmitter } from '@/hooks/useCtrlUpdate';
import useStorage from '@/hooks/useStorage';
import useTimeoutHanlder from '@/hooks/useTimeoutHanlder';
import { command } from '@/ts/base';
import orgCtrl from '@/ts/controller';
import { IFile, ISession, ITarget, IWorkTask } from '@/ts/core';
import { targetOperates } from '@/ts/core/public';
import { cleanMenus } from '@/utils/tools';
import { Button, Layout, Spin } from 'antd';
import { Resizable } from 'devextreme-react';
import React, { useEffect, useState } from 'react';
import { ImUndo2 } from 'react-icons/im';

const { Content, Sider } = Layout;

interface IProps {
  session: ISession;
  bodyType: string;
}
// 数据
const RelationDirectory: React.FC<IProps> = ({ session, bodyType }) => {
  const { target } = session;
  const [mainWidth, setMainWidth] = useStorage<string | number>('mainWidth', '40%');
  const [current, setCurrent] = useState<ITarget | 'disk'>('disk');
  const [currentTag, setCurrentTag] = useState('全部');
  const [focusFile, setFocusFile] = useState<IFile>();
  const [content, setContent] = useState<IFile[]>([]);
  const [submitHanlder, clearHanlder] = useTimeoutHanlder();
  const [loaded] = useFlagCmdEmitter('');

  useEffect(() => {
    if (content.length > 0) {
      setFocusFile(content[0]);
    }
  }, [content]);

  useEffect(() => {
    setContent(getTargetContent(session.target.key));
  }, [session]);

  useEffect(() => {
    setCurrentTag('全部');
    if (current === 'disk') {
      setContent(getTargetContent(session.target.key));
    } else {
      const updateContent = () => {
        if (current.typeName === '单位') {
          return setContent(getTargetContent(current.key));
        }
        return setContent(current.content());
      };
      current.subscribe(updateContent);
    }
  }, [current]);

  const getTargetContent = (key: string) => {
    const res = [orgCtrl.user, ...orgCtrl.user.companys].filter(
      (item) => item?.key === key,
    );
    const target = res?.[0];
    const contentList = typeof target?.content === 'function' ? target.content() : [];
    return target ? [target, ...contentList] : [];
  };

  const contextMenu = (file?: IFile) => {
    const entity = file ?? current;
    if (entity != 'disk') {
      return {
        items: cleanMenus(loadFileMenus(entity)) || [],
        onClick: ({ key }: { key: string }) => {
          command.emitter('executor', key, entity);
        },
      };
    } else {
      return {
        items:
          cleanMenus(
            operatesToMenus(
              [targetOperates.NewCompany, targetOperates.JoinCompany],
              orgCtrl.user,
            ),
          ) || [],
        onClick: ({ key }: { key: string }) => {
          command.emitter('executor', key, orgCtrl.user);
        },
      };
    }
  };

  const focusHanlder = (file: IFile | undefined) => {
    if (file && file.key !== focusFile?.key) {
      setFocusFile(file);
    }
  };

  const clickHanlder = (file: ITarget | undefined, dblclick: boolean) => {
    if (dblclick) {
      clearHanlder();
      if (file) {
        setCurrent(file);
      }
    } else {
      submitHanlder(() => focusHanlder(file), 300);
    }
  };

  const renderHeader = () => {
    return (
      <div style={{ marginLeft: 10, padding: 2, fontSize: 18, height: 28 }}>
        {current != 'disk' && (
          <Button
            type="link"
            title="返回"
            icon={<ImUndo2 />}
            onClick={() => {
              setFocusFile(current);
              setCurrent(current.superior as ITarget);
            }}
          />
        )}
      </div>
    );
  };

  return (
    <Layout className={'main_layout'}>
      <Layout className={'body'}>
        <Resizable
          handles={'right'}
          width={mainWidth}
          onResize={(e) => setMainWidth(e.width)}>
          <Sider className={'content'} width={'100%'}>
            <Spin spinning={!loaded} tip={'加载中...'}>
              {current != 'disk' && renderHeader()}
              <DirectoryViewer
                isMenu
                initTags={['全部']}
                selectFiles={[]}
                height={current != 'disk' ? 'calc(100vh - 180px)' : 'calc(100vh - 148px)'}
                extraTags={true}
                focusFile={focusFile}
                content={content}
                currentTag={currentTag}
                tagChanged={(t) => setCurrentTag(t)}
                fileOpen={(entity, dblclick) => clickHanlder(entity as ITarget, dblclick)}
                contextMenu={(entity) => contextMenu(entity as IWorkTask)}
              />
            </Spin>
          </Sider>
        </Resizable>
        <Content className={'content'}>
          <div
            style={{
              height: 'calc(100vh - 84px)',
            }}>
            <SessionBody
              key={focusFile?.key ?? target.key}
              bodyType={bodyType}
              height={'calc(100vh - 148px)'}
              session={focusFile?.session ?? target.session}
            />
          </div>
        </Content>
      </Layout>
    </Layout>
  );
};

export default RelationDirectory;
